﻿using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;

namespace WPay.Infrastructure.Unity
{
    /// <summary>
    /// Token授权码生成类
    /// </summary>
    public class IdentityServer
    {
        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="_appId">应用名称</param>
        /// <param name="_appType">应用类型</param>
        /// <param name="_appSecret">APP开发密钥</param>
        /// <param name="_expires">过期时间，单位：秒，默认3600秒</param>
        /// <returns>返回Token</returns>
        public static string CreateToken(string _appId, string _appSecret, string _appType, int _expires = 3600)
        {
            DateTime dt = DateTime.Now;
            Claim[] claims = new Claim[]
            {
                new Claim(JwtRegisteredClaimNames.Sub,_appType),//Subject,
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),//JWT ID,JWT的唯一标识
                new Claim(JwtRegisteredClaimNames.Iat, dt.ToString(), ClaimValueTypes.Integer64),//Issued At，JWT颁发的时间，采用标准unix时间，用于验证过期
               
            };

            JwtSecurityToken jwt = new JwtSecurityToken(
            issuer: "UN_CRM",//jwt签发者,非必须
            audience: _appId,//jwt的接收该方，非必须
            claims: claims,//声明集合
            expires: dt.AddSeconds(_expires),//指定token的生命周期，unix时间戳格式,非必须

            signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_appSecret)), SecurityAlgorithms.HmacSha256));//使用私钥进行签名加密

            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);//生成最后的JWT字符串
            return encodedJwt;
        }
        /// <summary>
        /// 读取token信息
        /// </summary>
        /// <param name="_token">token</param>
        /// <returns></returns>
        public static string ReadToken(string _token)
        {
            JwtSecurityToken jwt = new JwtSecurityTokenHandler().ReadJwtToken(_token);
            if (jwt == null || jwt.Claims == null) return null;
            //获取token信息
            List<Claim> claims = jwt.Claims.ToList();
            string sub = string.Empty, jti = string.Empty, iat = string.Empty, iss = string.Empty, aud = string.Empty;
            int exp = 0;
            for (int i = 0; i < claims.Count; i++)
            {
                Claim c = claims[i];
                switch (c.Type)
                {
                    case "sub"://Subject,App描述c.Value
                        sub = c.Value;
                        break;
                    case "jti"://JWT ID,JWT的唯一标识
                        jti = c.Value;
                        break;
                    case "iat"://JWT颁发的时间 
                        iat = c.Value;
                        break;
                    case "exp"://证书过期时间戳
                        exp = Convert.ToInt32(c.Value);
                        break;
                    case "iss"://jwt签发者,UN_CRM
                        iss = c.Value;
                        break;
                    case "aud"://jwt的接收该方，AppID
                        aud = c.Value;
                        break;
                }
            }

            if (TimestampTool.GetTimeSpan() > 120 + exp)//验证是否已过期
                return null;
            if (iss != "UN_CRM")//验证是否为 UM_CRM颁发的token
                return null;
            //验证通过，返回AppID
            return aud;
        }
    }
}
